home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / c_pretty_printer.e < prev    next >
Text File  |  2000-03-25  |  56KB  |  2,382 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class C_PRETTY_PRINTER
  17.    --
  18.    -- Singleton in charge of handling C code pretty printing.
  19.    -- This singleton is shared via the GLOBALS.`cpp' once function.
  20.    --
  21.  
  22. inherit CODE_PRINTER;
  23.  
  24. feature
  25.  
  26.    on_h: BOOLEAN is
  27.       require
  28.      small_eiffel.is_ready
  29.       do
  30.      Result := current_out = out_h;
  31.       end;
  32.  
  33.    on_c: BOOLEAN is
  34.       require
  35.      small_eiffel.is_ready
  36.       do
  37.      Result := current_out = out_c;
  38.       end;
  39.  
  40.    swap_on_c is
  41.       do
  42.      current_out := out_c;
  43.       ensure
  44.      on_c;
  45.       end;
  46.  
  47.    swap_on_h is
  48.       do
  49.      current_out := out_h;
  50.       ensure
  51.      on_h;
  52.       end;
  53.  
  54.    put_string_on_h(string: STRING) is
  55.       do
  56.      out_h.put_string(string);
  57.       end;
  58.  
  59.    put_extern1(decl: STRING) is
  60.       do
  61.      incr_elt_c_count(2);
  62.      out_h.put_string(fz_extern);
  63.      out_h.put_string(decl);
  64.      out_h.put_string(fz_00);
  65.      out_c.put_string(decl);
  66.      out_c.put_string(fz_00);
  67.       end;
  68.  
  69.    put_extern2(decl: STRING; init: CHARACTER) is
  70.       do
  71.      incr_elt_c_count(2);
  72.      out_h.put_string(fz_extern);
  73.      out_h.put_string(decl);
  74.      out_h.put_string(fz_00);
  75.      out_c.put_string(decl);
  76.      out_c.put_character('=');
  77.      out_c.put_character(init);
  78.      out_c.put_string(fz_00);
  79.       end;
  80.  
  81.    put_extern3(var, value: STRING) is
  82.       do
  83.      incr_elt_c_count(2);
  84.      out_c.put_string("char ");
  85.      out_c.put_string(var);
  86.      out_c.put_string("[]=%"");
  87.      out_c.put_string(value);
  88.      out_c.put_string("%";%N");
  89.      out_h.put_string("extern char ");
  90.      out_h.put_string(var);
  91.      out_h.put_character('[');
  92.      out_h.put_character(']');
  93.      out_h.put_string(fz_00);
  94.       end;
  95.  
  96.    put_extern4(t, var: STRING; value: INTEGER) is
  97.       do
  98.      incr_elt_c_count(2);
  99.      out_c.put_string(t);
  100.      out_c.put_character(' ');
  101.      out_c.put_string(var);
  102.      out_c.put_character('[');
  103.      out_c.put_integer(value);
  104.      out_c.put_string("];%N");
  105.      out_h.put_string(fz_extern);
  106.      out_h.put_string(t);
  107.      out_h.put_character(' ');
  108.      out_h.put_string(var);
  109.      out_h.put_character('[');
  110.      out_h.put_character(']');
  111.      out_h.put_string(fz_00);
  112.       end;
  113.  
  114.    put_extern5(decl: STRING; init: STRING) is
  115.       do
  116.      incr_elt_c_count(2);
  117.      out_h.put_string(fz_extern);
  118.      out_h.put_string(decl);
  119.      out_h.put_string(fz_00);
  120.      out_c.put_string(decl);
  121.      out_c.put_character('=');
  122.      out_c.put_string(init);
  123.      out_c.put_string(fz_00);
  124.       end;
  125.  
  126.    put_extern6(decl: STRING; init: INTEGER) is
  127.       do
  128.      incr_elt_c_count(2);
  129.      out_h.put_string(fz_extern);
  130.      out_h.put_string(decl);
  131.      out_h.put_string(fz_00);
  132.      out_c.put_string(decl);
  133.      out_c.put_character('=');
  134.      out_c.put_integer(init);
  135.      out_c.put_string(fz_00);
  136.       end;
  137.  
  138.    put_extern7(decl: STRING) is
  139.       do
  140.      incr_elt_c_count(2);
  141.      out_h.put_string(fz_extern);
  142.      out_h.put_string(decl);
  143.      out_h.put_string(fz_00);
  144.      out_c.put_string(decl);
  145.      out_c.put_character('=');
  146.       end;
  147.  
  148.    put_c_heading(heading: STRING) is
  149.       do
  150.      incr_elt_c_count(4);
  151.      out_h.put_string(heading);
  152.      out_h.put_string(fz_00);
  153.      out_c.put_string("%N%N");
  154.      out_c.put_string(heading);
  155.      out_c.put_string(fz_11);
  156.       end;
  157.  
  158.    put_c_function(heading, body:STRING) is
  159.       require
  160.      not heading.is_empty;
  161.      body /= Void
  162.       do
  163.      incr_elt_c_count(body.nb_occurrences('%N'));
  164.      put_c_heading(heading);
  165.      out_c.put_string(body);
  166.      out_c.put_string(fz_12);
  167.       end;
  168.  
  169.    put_string(c: STRING) is
  170.       require
  171.      small_eiffel.is_ready
  172.       do
  173.      current_out.put_string(c);
  174.       end;
  175.  
  176.    put_string_c(s: STRING) is
  177.       require
  178.      small_eiffel.is_ready;
  179.      on_c
  180.       do
  181.      tmp_string.clear;
  182.      manifest_string_pool.string_to_c_code(s,tmp_string);
  183.      out_c.put_string(tmp_string);
  184.       end;
  185.  
  186.    put_character(c: CHARACTER) is
  187.       require
  188.      small_eiffel.is_ready
  189.       do
  190.      current_out.put_character(c);
  191.       end;
  192.  
  193.    put_integer(i: INTEGER) is
  194.       require
  195.      small_eiffel.is_ready
  196.       do
  197.      current_out.put_integer(i);
  198.       end;
  199.  
  200.    put_real(r: REAL) is
  201.       require
  202.      small_eiffel.is_ready
  203.       do
  204.      current_out.put_real(r);
  205.       end;
  206.  
  207.    put_array1(array_name: CHARACTER; value: INTEGER) is
  208.       do
  209.      current_out.put_character(array_name);
  210.      current_out.put_character('[');
  211.      current_out.put_integer(value);
  212.      current_out.put_character(']');
  213.       end;
  214.  
  215.    put_se_string_from_external_copy(c_string: STRING) is
  216.       do
  217.      current_out.put_string("se_string_from_external_copy(");
  218.      put_string_c(c_string);
  219.      current_out.put_character(')');
  220.       end;
  221.  
  222.    put_position(p: POSITION) is
  223.       require
  224.      on_c;
  225.      small_eiffel.is_ready
  226.       do
  227.      out_c.put_integer(p.mangling.to_integer);
  228.       end;
  229.  
  230.    put_position_in_ds(p: POSITION) is
  231.       require
  232.      on_c;
  233.      small_eiffel.is_ready
  234.       do
  235.      out_c.put_string("ds.p=");
  236.      put_position(p);
  237.      out_c.put_string(fz_00);
  238.       end;
  239.  
  240.    put_target_as_target is
  241.      -- Produce C code to pass the current stacked target as
  242.      -- a target of a new call : user expanded are passed with
  243.      -- a pointer and class invariant code is produced.
  244.       require
  245.      small_eiffel.is_ready
  246.       local
  247.      code: INTEGER;
  248.      rf: RUN_FEATURE;
  249.      target: EXPRESSION;
  250.      args: EFFECTIVE_ARG_LIST;
  251.      ct: TYPE;
  252.      ivt_flag: BOOLEAN;
  253.       do
  254.      code := stack_code.item(top);
  255.      inspect
  256.         code
  257.      when C_direct_call then
  258.         target := stack_target.item(top);
  259.         rf := stack_rf.item(top);
  260.         ct := rf.current_type;
  261.         target.mapping_c_target(ct);
  262.      when C_check_id then
  263.         target := stack_target.item(top);
  264.         rf := stack_rf.item(top);
  265.         ct := rf.current_type;
  266.         check
  267.            ct.is_reference;
  268.         end;
  269.         if run_control.boost then
  270.            target.mapping_c_target(ct);
  271.         else
  272.            ivt_flag := call_invariant_start(ct);
  273.            check_id(target,rf.id);
  274.            if ivt_flag then
  275.           call_invariant_end;
  276.            end;
  277.         end;
  278.      when C_inline_dca then
  279.         put_character('(');
  280.         stack_rf.item(top).current_type.mapping_cast;
  281.         put_character('(');
  282.         put_target_as_value;
  283.         put_string(fz_13);
  284.      when C_same_target then
  285.         rf := stack_rf.item(top);
  286.         args := stack_args.item(top);
  287.         top := top - 1;
  288.         put_target_as_target;
  289.         top := top + 1;
  290.         stack_code.put(code,top);
  291.         stack_rf.put(rf,top);
  292.         stack_args.put(args,top);
  293.      else
  294.         common_put_target;
  295.      end;
  296.       end;
  297.  
  298.    put_target_as_value is
  299.      -- Produce C code for a simple access to the stacked target.
  300.      -- User's expanded values are not given using a pointer.
  301.      -- There is no C code to check the class invariant.
  302.       require
  303.      small_eiffel.is_ready
  304.       local
  305.      code: INTEGER;
  306.      rf, static_rf: RUN_FEATURE;
  307.      target: EXPRESSION;
  308.      args: EFFECTIVE_ARG_LIST;
  309.      c0c: CALL_0_C;
  310.      direct_rf: RUN_FEATURE;
  311.       do
  312.      code := stack_code.item(top);
  313.      inspect
  314.         code
  315.      when C_direct_call then
  316.         stack_target.item(top).compile_to_c;
  317.      when C_check_id then
  318.         stack_rf.item(top).current_type.mapping_cast;
  319.         stack_target.item(top).compile_to_c;
  320.      when C_inline_dca then
  321.         rf := stack_rf.item(top);
  322.         target := stack_target.item(top);
  323.         args := stack_args.item(top);
  324.         static_rf := stack_static_rf.item(top);
  325.         top := top - 1;
  326.         c0c ?= target;
  327.         direct_rf := c0c.run_feature;
  328.         direct_rf.mapping_c;
  329.         top := top + 1;
  330.         stack_code.put(code,top);
  331.         stack_rf.put(rf,top);
  332.         stack_target.put(target,top);
  333.         stack_args.put(args,top);
  334.         stack_static_rf.put(static_rf,top);
  335.      when C_same_target then
  336.         rf := stack_rf.item(top);
  337.         args := stack_args.item(top);
  338.         top := top - 1;
  339.         put_target_as_value;
  340.         top := top + 1;
  341.         stack_code.put(code,top);
  342.         stack_rf.put(rf,top);
  343.         stack_args.put(args,top);
  344.      else
  345.         common_put_target;
  346.      end;
  347.       end;
  348.  
  349.    put_error0(msg: STRING) is
  350.      -- Print `msg' and then stop execution.
  351.      -- Also print stack when not -boost.
  352.       do
  353.      put_string("error0(");
  354.      put_string_c(msg);
  355.      put_string(",NULL);%N");
  356.       end;
  357.  
  358.    put_comment(str: STRING) is
  359.       do
  360.      put_string(fz_open_c_comment);
  361.      put_string(str);
  362.      put_string(fz_close_c_comment);
  363.       end;
  364.  
  365.    put_comment_line(str: STRING) is
  366.       do
  367.      put_character('%N');
  368.      put_comment(str);
  369.      put_character('%N');
  370.       end;
  371.  
  372.    define_main(rf3: RUN_FEATURE_3) is
  373.       do
  374.      swap_on_c;
  375.      -- Declare eiffel_root_object :
  376.      tmp_string.clear;
  377.      tmp_string.extend('T');
  378.      rf3.run_class.id.append_in(tmp_string);
  379.      tmp_string.append("*eiffel_root_object");
  380.      put_extern5(tmp_string,fz_null);
  381.      -- Save argv argc :
  382.      put_extern1("int se_argc");
  383.      put_extern1("char**se_argv");
  384.      define_initialize_eiffel_runtime(rf3);
  385.      if not no_main then
  386.         really_define_c_main(rf3);
  387.      end;
  388.      incr_elt_c_count(4);
  389.       end;
  390.  
  391.    trace_boolean_expression(e: EXPRESSION) is
  392.      -- Produce a C boolean expression including trace code.
  393.       require
  394.      e.result_type.is_boolean;
  395.      run_control.no_check;
  396.       do
  397.      put_character('(');
  398.      se_trace_exp(e.start_position);
  399.      put_character(',');
  400.      e.compile_to_c;
  401.      put_character(')');
  402.       end;
  403.  
  404. feature {SMALL_EIFFEL}
  405.  
  406.    get_started is
  407.       require
  408.      small_eiffel.is_ready
  409.       local
  410.      no_check: BOOLEAN;
  411.       do
  412.      echo.file_removing(path_make);
  413.      no_check := run_control.no_check;
  414.      top := -1;
  415.      if no_split then
  416.         echo.sfw_connect(out_c,path_c);
  417.      else
  418.         backup_sfw_connect(out_c,path_c);
  419.      end;
  420.      current_out := out_c;
  421.      add_first_include(path_h);
  422.      !!out_h.make;
  423.      echo.sfw_connect(out_h,path_h);
  424.      current_out := out_h;
  425.      put_banner(out_h);
  426.      out_h.put_character('%N');
  427.      sys_runtime_h(fz_base);
  428.      current_out := out_c;
  429.       ensure
  430.      on_c
  431.       end;
  432.  
  433.    cecil_define is
  434.       local
  435.      save_out_h: like out_h;
  436.       do
  437.      save_out_h := out_h;
  438.      cecil_pool.c_define_users;
  439.      out_h := save_out_h;
  440.       end;
  441.  
  442.    define_used_basics is
  443.      -- Produce C code only when used.
  444.       local
  445.      no_check: BOOLEAN;
  446.       do
  447.      no_check := run_control.no_check;
  448.      echo.put_string("Define used basics.%N");
  449.      conversion_handler.c_definitions;
  450.      bit_constant_definition;
  451.      if sure_void_count > 0 then
  452.         echo.put_string("Calls with a Void target : ");
  453.         echo.put_integer(sure_void_count);
  454.         echo.put_string(" (yes it is dangerous).%N");
  455.      end;
  456.      echo.print_count("Direct Call",direct_call_count);
  457.      echo.print_count("Check Id Call",check_id_count);
  458.      echo.print_count("Switched Call",switch_count);
  459.      echo.print_count("Inlined Procedure",inlined_procedure_count);
  460.      echo.print_count("Inlined Function",inlined_function_count);
  461.      echo.print_count("Static Expression",static_expression_count);
  462.      echo.print_count("Procedure",procedure_count);
  463.      echo.print_count("Function",function_count);
  464.      echo.print_count("Procedure without Current",real_procedure_count);
  465.      echo.print_count("Function without Current",real_function_count);
  466.      echo.print_count("Precursor routine",precursor_routine_count);
  467.      echo.put_string("Internal stacks size used : ");
  468.      echo.put_integer(stack_code.count);
  469.      echo.put_character('%N');
  470.      end;
  471.  
  472.     customize_runtime(basic_sys_runtime: FIXED_ARRAY[STRING]) is
  473.       local
  474.      i: INTEGER;
  475.       do
  476.      if run_control.no_check then
  477.         sys_runtime_h_and_c("no_check");
  478.         if run_control.trace then
  479.            put_extern2("int se_trace_flag",'0');
  480.            out_h.put_string("#define SE_TRACE 1%N");
  481.         elseif wedit then
  482.            out_h.put_string("#define SE_WEDIT 1%N");
  483.         end;
  484.         sys_runtime_h_and_c("trace");
  485.      else
  486.         sys_runtime_h_and_c("boost");
  487.      end;
  488.      if run_control.deep_twin_used then
  489.         sys_runtime_h_and_c(as_deep_twin);
  490.      end;
  491.      if basic_sys_runtime /= void then
  492.         from
  493.            i := basic_sys_runtime.upper;
  494.         until
  495.            i < 0
  496.         loop
  497.            sys_runtime_h_and_c(basic_sys_runtime.item(i));
  498.            i := i - 1;
  499.         end;
  500.      end;
  501.      exceptions_handler.get_started;
  502.       end;
  503.  
  504. feature {RUN_FEATURE,NATIVE}
  505.  
  506.    target_cannot_be_dropped: BOOLEAN is
  507.      -- True when top target cannot be dropped because we are
  508.      -- not sure that target is non Void or that target has
  509.      -- no side effects. When Result is true, printed
  510.      -- C code is : "(((void)(<target>))"
  511.       require
  512.      small_eiffel.is_ready
  513.       local
  514.      target: EXPRESSION;
  515.      target_type: TYPE;
  516.       do
  517.      inspect
  518.         stack_code.item(top)
  519.      when C_direct_call, C_check_id then
  520.         target := stack_target.item(top);
  521.         target_type := target.result_type;
  522.         Result := not target.can_be_dropped;
  523.      when C_inline_dca then
  524.         Result := true;
  525.      when C_same_target then
  526.         top := top - 1;
  527.         Result := target_cannot_be_dropped;
  528.         top := top + 1;
  529.      else
  530.      end;
  531.      if Result then
  532.         put_string("((/*UT*/(void)(");
  533.         if target_type = Void then
  534.            put_target_as_target;
  535.         elseif target_type.is_user_expanded then
  536.            put_target_as_value;
  537.         else
  538.            put_target_as_target;
  539.         end;
  540.         put_string(fz_13);
  541.      end;
  542.       end;
  543.  
  544.    arguments_cannot_be_dropped: BOOLEAN is
  545.      -- True when arguments cannot be dropped.
  546.      -- Printed C code is like :
  547.      --  "(((void)<exp1>),((void)<exp2>),...((void)<expN>)"
  548.       do
  549.      if not no_args_to_eval then
  550.         Result := true;
  551.         put_string("((/*UA*/(void)(");
  552.         put_arguments;
  553.         put_string(fz_13);
  554.      end;
  555.       end;
  556.  
  557.    cannot_drop_all: BOOLEAN is
  558.      -- Result is true when something (target or one argument)
  559.      -- cannot be dropped. Thus when something cannot be dropped,
  560.      -- Result is true and C code is printed :
  561.      --  "(((void)<exp1>),((void)<exp2>),...((void)<expN>)"
  562.       do
  563.      if target_cannot_be_dropped then
  564.         Result := true;
  565.         put_character(',');
  566.         if arguments_cannot_be_dropped then
  567.            put_character(')');
  568.         else
  569.            put_character('0');
  570.         end;
  571.      else
  572.         Result := arguments_cannot_be_dropped;
  573.      end;
  574.       end;
  575.  
  576. feature
  577.  
  578.    put_arguments is
  579.      -- Produce code to access effective arguments list.
  580.       require
  581.      small_eiffel.is_ready
  582.       local
  583.      code: INTEGER;
  584.      rf, static_rf: RUN_FEATURE;
  585.      target: EXPRESSION;
  586.      args: EFFECTIVE_ARG_LIST;
  587.      fal: FORMAL_ARG_LIST;
  588.      switch: SWITCH;
  589.       do
  590.      code := stack_code.item(top);
  591.      inspect
  592.         code
  593.      when C_expanded_initialize then
  594.      when C_inside_twin then
  595.         put_ith_argument(1);
  596.      when C_direct_call then
  597.         fal := stack_rf.item(top).arguments;
  598.         stack_args.item(top).compile_to_c(fal);
  599.      when C_check_id then
  600.         fal := stack_rf.item(top).arguments;
  601.         stack_args.item(top).compile_to_c(fal);
  602.      when C_switch then
  603.         fal := stack_rf.item(top).arguments;
  604.         static_rf := stack_static_rf.item(top);
  605.         switch.put_arguments(static_rf,fal);
  606.      when C_inside_new then
  607.         fal := stack_rf.item(top).arguments;
  608.         stack_args.item(top).compile_to_c(fal);
  609.      when C_inline_dca then
  610.         rf := stack_rf.item(top);
  611.         target := stack_target.item(top);
  612.         args := stack_args.item(top);
  613.         static_rf := stack_static_rf.item(top);
  614.         top := top - 1;
  615.         args.dca_inline(rf.arguments);
  616.         top := top + 1;
  617.         stack_code.put(code,top);
  618.         stack_rf.put(rf,top);
  619.         stack_target.put(target,top);
  620.         stack_args.put(args,top);
  621.         stack_static_rf.put(static_rf,top);
  622.      when C_same_target then
  623.         fal := stack_rf.item(top).arguments;
  624.         stack_args.item(top).compile_to_c(fal);
  625.      when C_inline_one_pc then
  626.      when C_precursor then
  627.         fal := stack_rf.item(top).arguments;
  628.         stack_args.item(top).compile_to_c(fal);
  629.      end;
  630.       end;
  631.  
  632.    put_ith_argument(index: INTEGER) is
  633.      -- Produce code to access to the ith argument.
  634.       require
  635.      small_eiffel.is_ready
  636.      index >= 1
  637.       local
  638.      code: INTEGER;
  639.      rf, static_rf: RUN_FEATURE;
  640.      target: EXPRESSION;
  641.      args: EFFECTIVE_ARG_LIST;
  642.      fal: FORMAL_ARG_LIST;
  643.      switch: SWITCH;
  644.       do
  645.      code := stack_code.item(top);
  646.      inspect
  647.         code
  648.      when C_direct_call then
  649.         fal := stack_rf.item(top).arguments;
  650.         stack_args.item(top).compile_to_c_ith(fal,index);
  651.      when C_check_id then
  652.         fal := stack_rf.item(top).arguments;
  653.         stack_args.item(top).compile_to_c_ith(fal,index);
  654.      when C_switch then
  655.         fal := stack_rf.item(top).arguments;
  656.         static_rf := stack_static_rf.item(top);
  657.         switch.put_ith_argument(static_rf,fal,index);
  658.      when C_inside_new then
  659.         fal := stack_rf.item(top).arguments;
  660.         stack_args.item(top).compile_to_c_ith(fal,index);
  661.      when C_inline_dca then
  662.         rf := stack_rf.item(top);
  663.         target := stack_target.item(top);
  664.         args := stack_args.item(top);
  665.         static_rf := stack_static_rf.item(top);
  666.         top := top - 1;
  667.         if rf /= Void then
  668.            args.dca_inline_ith(rf.arguments,index);
  669.         else
  670.            -- No rf for "=" and "/=".
  671.            args.dca_inline_ith(static_rf.arguments,index);
  672.         end;
  673.         top := top + 1;
  674.         stack_code.put(code,top);
  675.         stack_rf.put(rf,top);
  676.         stack_target.put(target,top);
  677.         stack_args.put(args,top);
  678.         stack_static_rf.put(static_rf,top);
  679.      when C_same_target then
  680.         fal := stack_rf.item(top).arguments;
  681.         stack_args.item(top).compile_to_c_ith(fal,index);
  682.      when C_inline_one_pc then
  683.         print_argument(index);
  684.      when C_inside_twin then
  685.         check
  686.            index = 1
  687.         end;
  688.         if stack_rf.item(top).current_type.is_reference then
  689.            put_string("((T0*)C)");
  690.         else
  691.            put_string("*C");
  692.         end;
  693.      end;
  694.       end;
  695.  
  696. feature {NATIVE_SMALL_EIFFEL}
  697.  
  698.    put_c_inline_h is
  699.       local
  700.      c_code: STRING;
  701.       do
  702.      c_code := get_inline_ms.to_string;
  703.      if not c_inline_h_mem.fast_has(c_code) then
  704.         c_inline_h_mem.add_last(c_code);
  705.         out_h.put_string(c_code);
  706.         out_h.put_character('%N');
  707.      end;
  708.       end;
  709.  
  710.    put_c_inline_c is
  711.       local
  712.      c_code: MANIFEST_STRING;
  713.       do
  714.      c_code := get_inline_ms;
  715.      out_c.put_string(c_code.to_string);
  716.       end;
  717.  
  718.    put_trace_switch is
  719.       do
  720.      if run_control.trace then
  721.         put_string("se_trace_flag=(");
  722.         put_ith_argument(1);
  723.         put_string(fz_14);
  724.      end;
  725.       end;
  726.  
  727. feature {NATIVE_SMALL_EIFFEL}
  728.  
  729.    put_generating_type(t: TYPE) is
  730.       local
  731.      rc: RUN_CLASS;
  732.       do
  733.      put_string(fz_cast_t0_star);
  734.      put_character('(');
  735.      put_character('t');
  736.      put_character('[');
  737.      if t.is_reference then
  738.         rc := t.run_class;
  739.         if rc.is_tagged then
  740.            put_character('(');
  741.            put_target_as_value;
  742.            put_character(')');
  743.            put_string(fz_arrow_id);
  744.         else
  745.            put_integer(rc.id);
  746.         end;
  747.      else
  748.         put_integer(t.id);
  749.      end;
  750.      put_character(']');
  751.      put_character(')');
  752.       end;
  753.  
  754.    put_generator(t: TYPE) is
  755.       require
  756.      t.is_run_type;
  757.       local
  758.      rc: RUN_CLASS;
  759.       do
  760.      put_string(fz_cast_t0_star);
  761.      put_character('(');
  762.      put_character('g');
  763.      put_character('[');
  764.      if t.is_reference then
  765.         rc := t.run_class;
  766.         if rc.is_tagged then
  767.            put_character('(');
  768.            put_target_as_value;
  769.            put_character(')');
  770.            put_string(fz_arrow_id);
  771.         else
  772.            put_integer(rc.id);
  773.         end;
  774.      else
  775.         put_integer(t.id);
  776.      end;
  777.      put_character(']');
  778.      put_character(')');
  779.       end;
  780.  
  781.    put_to_pointer is
  782.       do
  783.      put_string("((void*)");
  784.      put_target_as_value;
  785.      put_character(')');
  786.       end;
  787.  
  788.    put_object_size(t: TYPE) is
  789.       require
  790.      t.is_run_type;
  791.       local
  792.      tcbd: BOOLEAN;
  793.       do
  794.      tcbd := target_cannot_be_dropped;
  795.      if tcbd then
  796.         out_c.put_character(',');
  797.      end;
  798.      out_c.put_string("sizeof(T");
  799.      out_c.put_integer(t.id);
  800.      out_c.put_character(')');
  801.      if tcbd then
  802.         out_c.put_character(')');
  803.      end;
  804.       end;
  805.  
  806. feature {CECIL_POOL}
  807.  
  808.    connect_cecil_out_h(user_path_h: STRING) is
  809.       do
  810.      !!out_h.make;
  811.      echo.sfw_connect(out_h,user_path_h);
  812.      sys_runtime_h(fz_base);
  813.      out_h.put_string(
  814.               "extern void*eiffel_root_object;%N%N%
  815.               %typedef char* T9;%N%
  816.               %/* Available Eiffel routines via -cecil:%N*/%N");
  817.       end;
  818.  
  819.    disconnect_cecil_out_h is
  820.       do
  821.      out_h.disconnect;
  822.       end;
  823.  
  824. feature {CECIL_POOL,RUN_FEATURE}
  825.  
  826.    push_direct(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  827.       require
  828.      rf /= Void;
  829.      t /= Void
  830.       do
  831.      stack_push(C_direct_call);
  832.      stack_rf.put(rf,top);
  833.      stack_target.put(t,top);
  834.      stack_args.put(args,top);
  835.      direct_call_count := direct_call_count + 1;
  836.       end;
  837.  
  838. feature {RUN_FEATURE_3}
  839.  
  840.    push_inline_one_pc is
  841.       do
  842.      stack_push(C_inline_one_pc);
  843.       end;
  844.  
  845. feature {RUN_FEATURE_3,RUN_FEATURE_4}
  846.  
  847.    push_inline_dca(relay_rf: RUN_FEATURE; dpca: CALL_PROC_CALL) is
  848.      -- Where `dpca' is inside `relay_rf'.
  849.       require
  850.      relay_rf /= Void;
  851.      dpca /= Void
  852.       do
  853.      stack_push(C_inline_dca);
  854.      stack_rf.put(dpca.run_feature,top);
  855.      stack_static_rf.put(relay_rf,top);
  856.      stack_target.put(dpca.target,top);
  857.      stack_args.put(dpca.arguments,top);
  858.      direct_call_count := direct_call_count + 1;
  859.       end;
  860.  
  861.    push_same_target(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  862.       require
  863.      rf /= Void
  864.       do
  865.      stack_push(C_same_target);
  866.      stack_rf.put(rf,top);
  867.      stack_args.put(args,top);
  868.       end;
  869.  
  870. feature {CECIL_POOL}
  871.  
  872.    push_cpc(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS];
  873.         t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  874.       local
  875.      dyn_rf: RUN_FEATURE;
  876.       do
  877.      if r = Void then
  878.         se_evobt(up_rf,t);
  879.      elseif r.count = 1 then
  880.         dyn_rf := r.first.dynamic(up_rf);
  881.         push_check(dyn_rf,t,args);
  882.         dyn_rf.mapping_c;
  883.         pop;
  884.      else
  885.         use_switch(up_rf,r,t,args);
  886.      end;
  887.       end;
  888.  
  889. feature {SWITCH}
  890.  
  891.    inside_switch_call(dyn_rf, static_rf: RUN_FEATURE) is
  892.      -- Call the `dyn_rf' inside switching function for `static_rf'.
  893.       require
  894.      dyn_rf /= Void;
  895.      static_rf /= Void;
  896.      dyn_rf.run_class.dynamic(static_rf) = dyn_rf
  897.       local
  898.      dyn_result, static_result: TYPE;
  899.      cast, need_se_tmp: BOOLEAN;
  900.       do
  901.      -- Extra comment to debug C code :
  902.      -- put_comment(dyn_rf.current_type.run_time_mark);
  903.      --
  904.      dyn_rf.collect_c_tmp;
  905.      need_se_tmp := se_tmp_open_declaration;
  906.      static_result := static_rf.result_type;
  907.      -- Opening section for Result :
  908.      if static_result /= Void then
  909.         dyn_result := dyn_rf.result_type;
  910.         out_c.put_string("R=(");
  911.         if static_result.is_native_array then
  912.            cast := true;
  913.            out_c.put_string(fz_b7);
  914.            out_c.put_integer(static_result.id);
  915.            out_c.put_character(')');
  916.            out_c.put_character('(');
  917.         end;
  918.         if dyn_result.is_expanded and then static_result.is_reference then
  919.            conversion_handler.c_function_call(dyn_result,static_result);
  920.         end;
  921.      end;
  922.      stack_push(C_switch);
  923.      stack_rf.put(dyn_rf,top);
  924.      stack_static_rf.put(static_rf,top);
  925.      dyn_rf.mapping_c;
  926.      pop;
  927.      -- Closing section for Result :
  928.      if static_result /= Void then
  929.         if dyn_result.is_expanded and then static_result.is_reference then
  930.            out_c.put_character(')');
  931.         end;
  932.         if cast then
  933.            out_c.put_character(')');
  934.            out_c.put_character(')');
  935.         end;
  936.         out_c.put_string(fz_14);
  937.      end;
  938.      if need_se_tmp then
  939.         se_tmp_close_declaration;
  940.      end;
  941.       end;
  942.  
  943. feature {CREATION_CALL_3_4,LOCAL_VAR_LIST}
  944.  
  945.    expanded_writable(rf3: RUN_FEATURE_3; writable: EXPRESSION) is
  946.      -- Call the expanded initializer `rf3' using `writable'
  947.      -- as target.
  948.       require
  949.      rf3.current_type.is_expanded;
  950.      writable /= Void
  951.       do
  952.      stack_push(C_expanded_initialize);
  953.      stack_target.put(writable,top);
  954.      stack_rf.put(Void,top); -- *** UNNEEDED ???
  955.      direct_call_count := direct_call_count + 1;
  956.      rf3.mapping_c;
  957.      pop;
  958.      if call_invariant_start(rf3.current_type) then
  959.         put_character('&');
  960.         writable.compile_to_c;
  961.         call_invariant_end;
  962.         put_string(fz_00);
  963.      end;
  964.       end;
  965.  
  966. feature {CREATION_CALL}
  967.  
  968.    push_new(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  969.       require
  970.      rf /= Void;
  971.       do
  972.      stack_push(C_inside_new);
  973.      stack_rf.put(rf,top);
  974.      stack_args.put(args,top);
  975.      direct_call_count := direct_call_count + 1;
  976.       end;
  977.  
  978. feature {NATIVE}
  979.  
  980.    inside_twin(cpy: RUN_FEATURE) is
  981.       do
  982.      stack_push(C_inside_twin);
  983.      stack_rf.put(cpy,top);
  984.      cpy.mapping_c;
  985.      pop;
  986.       end;
  987.  
  988. feature {ASSERTION}
  989.  
  990.    check_assertion(e: EXPRESSION; tag_name: TAG_NAME) is
  991.      -- Produce a C boolean expression including trace code
  992.      -- and assertion check.
  993.       require
  994.      e.result_type.is_boolean
  995.       do
  996.      se_trace_ins(e.start_position);
  997.      put_string("ac_");
  998.      put_string(check_assertion_mode);
  999.      put_character('(');
  1000.      if e.is_static then
  1001.         static_expression_count := static_expression_count + 1;
  1002.      end;
  1003.      e.compile_to_c;
  1004.      put_character(',');
  1005.      if tag_name /= Void then
  1006.         put_string_c(tag_name.to_string);
  1007.      else
  1008.         put_string(fz_null);
  1009.      end;
  1010.      put_string(fz_14);
  1011.      elt_c_count := elt_c_count + 1;
  1012.       end;
  1013.  
  1014. feature {ASSERTION_LIST}
  1015.  
  1016.    set_check_assertion_mode(s: STRING) is
  1017.       require
  1018.      s /= Void
  1019.       do
  1020.      check_assertion_mode := s;
  1021.       ensure
  1022.      check_assertion_mode = s
  1023.       end;
  1024.  
  1025.    increment_static_expression_count(increment: INTEGER) is
  1026.       do
  1027.      static_expression_count := static_expression_count + increment;
  1028.       end;
  1029.  
  1030. feature
  1031.  
  1032.    se_trace_ins(p: POSITION) is
  1033.       do
  1034.      if run_control.no_check then
  1035.         se_trace_exp(p);
  1036.         out_c.put_string(fz_00);
  1037.      end;
  1038.       end;
  1039.  
  1040.    se_trace_exp(p: POSITION) is
  1041.       do
  1042.      if run_control.no_check then
  1043.         if run_control.trace then
  1044.            out_c.put_string("se_trace(&ds,");
  1045.         elseif wedit then
  1046.            out_c.put_string("se_trace(&ds,");
  1047.         else
  1048.            out_c.put_string("(ds.p=");
  1049.         end;
  1050.         put_position(p);
  1051.         out_c.put_character(')');
  1052.      end;
  1053.       end;
  1054.  
  1055. feature -- Numbering of inspect variables :
  1056.  
  1057.    inspect_incr is
  1058.       do
  1059.      inspect_level := inspect_level + 1;
  1060.       end;
  1061.  
  1062.    inspect_decr is
  1063.       do
  1064.      inspect_level := inspect_level - 1;
  1065.       end;
  1066.  
  1067.    put_inspect is
  1068.       do
  1069.      put_character('z');
  1070.      put_integer(inspect_level);
  1071.       end;
  1072.  
  1073. feature -- Printing Current, local or argument :
  1074.  
  1075.    inline_level_incr is
  1076.       do
  1077.      inline_level := inline_level + 1;
  1078.       end;
  1079.  
  1080.    inline_level_decr is
  1081.       do
  1082.      inline_level := inline_level - 1;
  1083.       end;
  1084.  
  1085.    print_current is
  1086.       require
  1087.      on_c
  1088.       local
  1089.      level: INTEGER;
  1090.       do
  1091.      out_c.put_character('C');
  1092.      level := inline_level;
  1093.      if level > 0 then
  1094.         out_c.put_integer(level);
  1095.      end;
  1096.       end;
  1097.  
  1098.    print_argument(rank: INTEGER) is
  1099.       require
  1100.      on_c
  1101.       local
  1102.      code: INTEGER;
  1103.       do
  1104.      code := ('a').code + inline_level;
  1105.      out_c.put_character(code.to_character);
  1106.      out_c.put_integer(rank);
  1107.       end;
  1108.  
  1109.    print_local(name: STRING) is
  1110.       require
  1111.      on_c
  1112.       local
  1113.      level: INTEGER;
  1114.       do
  1115.      from
  1116.         level := inline_level + 1;
  1117.      until
  1118.         level = 0
  1119.      loop
  1120.         out_c.put_character('_');
  1121.         level := level - 1;
  1122.      end;
  1123.      out_c.put_string(name);
  1124.       end;
  1125.  
  1126. feature {E_LOOP}
  1127.  
  1128.    variant_check(e: EXPRESSION) is
  1129.       do
  1130.      se_trace_ins(e.start_position);
  1131.      put_string("v=ac_lvc(c++,v,");
  1132.      e.compile_to_c;
  1133.      put_string(fz_14);
  1134.       end;
  1135.  
  1136. feature {RUN_FEATURE}
  1137.  
  1138.    current_class_invariant(current_type: TYPE) is
  1139.      -- Add some C code to check class invariant with Current
  1140.      -- at the end of a routine for `Current'.
  1141.       require
  1142.      current_type.is_run_type
  1143.       local
  1144.      rc: RUN_CLASS;
  1145.       do
  1146.      rc := need_invariant(current_type);
  1147.      if rc /= Void then
  1148.         if rc.current_type.is_reference then
  1149.            out_c.put_string("if(se_rci(C))");
  1150.         end;
  1151.         out_c.put_string(fz_se_i);
  1152.         out_c.put_integer(rc.id);
  1153.         out_c.put_string("(&ds,C);%N");
  1154.      end;
  1155.       end;
  1156.  
  1157. feature
  1158.  
  1159.    call_invariant_start(target_type: TYPE): BOOLEAN is
  1160.      -- Start printing call of invariant only when it is needed
  1161.      -- (`target_type' really has an invariant and when mode is
  1162.      -- `-invariant_check').
  1163.      -- When Result is true, `call_invariant_end' must be called to
  1164.      -- finish the job.
  1165.       require
  1166.      target_type.is_run_type;
  1167.       local
  1168.      rc: RUN_CLASS;
  1169.       do
  1170.      rc := need_invariant(target_type);
  1171.      if rc /= Void then
  1172.         out_c.put_string(fz_se_i);
  1173.         out_c.put_integer(rc.id);
  1174.         out_c.put_string("(&ds,");
  1175.         Result := true;
  1176.      end;
  1177.       end;
  1178.  
  1179.    call_invariant_end is
  1180.       do
  1181.      out_c.put_character(')');
  1182.       end;
  1183.  
  1184. feature
  1185.  
  1186.    macro_def(str: STRING; id: INTEGER) is
  1187.       do
  1188.      tmp_string.clear;
  1189.      tmp_string.extend('#');
  1190.      tmp_string.append(fz_define);
  1191.      tmp_string.extend(' ');
  1192.      tmp_string.append(str);
  1193.      tmp_string.extend(' ');
  1194.      id.append_in(tmp_string);
  1195.      tmp_string.extend('%N');
  1196.      out_h.put_string(tmp_string);
  1197.       end;
  1198.  
  1199. feature {CREATION_CALL}
  1200.  
  1201.    expanded_attributes(rt: TYPE) is
  1202.      -- Produce C code to initialize expanded attribute
  1203.      -- of the new object juste created in variable "n".
  1204.       require
  1205.      small_eiffel.is_ready;
  1206.      rt.is_run_type
  1207.       local
  1208.      wa: ARRAY[RUN_FEATURE];
  1209.      a: RUN_FEATURE;
  1210.      at: TYPE;
  1211.      i: INTEGER;
  1212.      rf3: RUN_FEATURE_3;
  1213.       do
  1214.      wa := rt.run_class.writable_attributes;
  1215.      if wa /= Void then
  1216.         from
  1217.            i := wa.upper;
  1218.         until
  1219.            i = 0
  1220.         loop
  1221.            a := wa.item(i);
  1222.            at := a.result_type.run_type;
  1223.  
  1224.            rf3 := at.expanded_initializer;
  1225.            if rf3 /= Void then
  1226.           stack_push(C_expanded_initialize);
  1227.           stack_target.put(Void,top);
  1228.           stack_rf.put(a,top);
  1229.           direct_call_count := direct_call_count + 1;
  1230.           rf3.mapping_c;
  1231.           pop;
  1232.            end;
  1233.            i := i - 1;
  1234.         end;
  1235.      end;
  1236.       end;
  1237.  
  1238. feature
  1239.  
  1240.    set_no_split is
  1241.       do
  1242.      no_split := true;
  1243.       end;
  1244.  
  1245.    write_make_file is
  1246.       local
  1247.      score: DOUBLE;
  1248.       do
  1249.      --
  1250.      out_h.put_character('%N');
  1251.       out_h.disconnect;
  1252.       out_c.put_character('%N');
  1253.       out_c.disconnect;
  1254.       --
  1255.       c_plus_plus_definitions;
  1256.    echo.sfw_connect(out_make,path_make);
  1257.      if no_split then
  1258.         write_make_file_no_split;
  1259.      else
  1260.         write_make_file_split;
  1261.      end;
  1262.      if system_tools.strip_executable(tmp_string) then
  1263.         echo_make;
  1264.      end;
  1265.      out_make.disconnect;
  1266.      if nb_errors > 0 then
  1267.         echo.file_removing(path_make);
  1268.      else
  1269.         echo.put_string("Type inference score : ");
  1270.         score := direct_call_count + check_id_count;
  1271.         score := (score / (score + switch_count)) * 100.0;
  1272.         echo.put_double_format(score,2);
  1273.         echo.put_character('%%');
  1274.         echo.put_character('%N');
  1275.      end;
  1276.      eiffel_parser.show_nb_warnings;
  1277.      eiffel_parser.show_nb_errors;
  1278.      echo.put_string(fz_02);
  1279.       end;
  1280.  
  1281. feature {C_PRETTY_PRINTER}
  1282.  
  1283.    no_split: BOOLEAN;
  1284.      -- True when the "-no_split" flag is in use.
  1285.  
  1286. feature {CALL_PROC_CALL}
  1287.  
  1288.    put_cpc(cpc: CALL_PROC_CALL) is
  1289.       local
  1290.      target: EXPRESSION;
  1291.      target_type: TYPE;
  1292.      run_feature: RUN_FEATURE;
  1293.       do
  1294.      target := cpc.target;
  1295.      target_type := target.result_type.run_type;
  1296.      run_feature := cpc.run_feature;
  1297.      if target_type.is_expanded then
  1298.         push_direct(run_feature,target,cpc.arguments);
  1299.         run_feature.mapping_c;
  1300.         pop;
  1301.      elseif target.is_current then
  1302.         push_direct(run_feature,target,cpc.arguments);
  1303.         run_feature.mapping_c;
  1304.         pop;
  1305.      elseif target.is_manifest_string then
  1306.         push_direct(run_feature,target,cpc.arguments);
  1307.         run_feature.mapping_c;
  1308.         pop;
  1309.      else
  1310.         push_cpc(run_feature,
  1311.              target_type.run_class.running,
  1312.              target,
  1313.              cpc.arguments);
  1314.      end;
  1315.       end;
  1316.  
  1317. feature
  1318.  
  1319.    sys_runtime_h(name: STRING) is
  1320.      -- Inline corresponding SmallEiffel/sys/runtime/`name'.h file.
  1321.       require
  1322.      name /= Void
  1323.       do
  1324.      system_tools.sys_runtime(name,'h');
  1325.      put_file(tmp_file_read,out_h);
  1326.       end;
  1327.  
  1328.    sys_runtime_c(name: STRING) is
  1329.      -- Inline corresponding SmallEiffel/sys/runtime/`name'.c file.
  1330.       require
  1331.      name /= Void
  1332.       do
  1333.      system_tools.sys_runtime(name,'c');
  1334.      put_file(tmp_file_read,out_c);
  1335.       end;
  1336.  
  1337.    sys_runtime_h_and_c(name: STRING) is
  1338.       do
  1339.      sys_runtime_h(name);
  1340.      sys_runtime_c(name);
  1341.       end;
  1342.  
  1343. feature {SYSTEM_TOOLS}
  1344.  
  1345.    put_c_file(sfr: STD_FILE_READ) is
  1346.       require
  1347.      not sfr.end_of_input
  1348.       do
  1349.      put_file(sfr,out_c);
  1350.       ensure
  1351.      not sfr.is_connected
  1352.       end;
  1353.  
  1354. feature
  1355.  
  1356.    put_recompilation_comment(key: INTEGER) is
  1357.       do
  1358.      out_c.put_string(fz_open_c_comment);
  1359.      out_c.put_integer(key);
  1360.      out_c.put_string(fz_close_c_comment);
  1361.       end;
  1362.  
  1363. feature
  1364.  
  1365.    no_main: BOOLEAN;
  1366.  
  1367.    set_no_main is
  1368.       do
  1369.      no_main := true;
  1370.       ensure
  1371.      no_main
  1372.       end;
  1373.  
  1374. feature {COMPILE_TO_C}
  1375.  
  1376.    wedit: BOOLEAN;
  1377.      -- When the code is generated for lcc/wedit (the -wedit flag).
  1378.  
  1379.    set_wedit(value: BOOLEAN) is
  1380.       do
  1381.      wedit := value;
  1382.       end;
  1383.  
  1384. feature {COMPOUND}
  1385.  
  1386.    one_more_instruction_generated is
  1387.       do
  1388.      elt_c_count := elt_c_count + 1;
  1389.       end;
  1390.  
  1391. feature {COMPOUND,ASSERTION_LIST,E_LOOP}
  1392.  
  1393.    se_tmp_open_declaration: BOOLEAN is
  1394.      -- True if some `se_tmpXX' is needed.
  1395.       local
  1396.      i: INTEGER;
  1397.      rf: RUN_FEATURE;
  1398.       do
  1399.      from
  1400.         tmp_string.clear;
  1401.         tmp_string.extend('{');
  1402.         i := se_tmp_list.upper;
  1403.      until
  1404.         i < 0
  1405.      loop
  1406.         rf := se_tmp_list.item(i);
  1407.         if rf /= Void then
  1408.            Result := true;
  1409.            rf.result_type.c_type_for_result_in(tmp_string);
  1410.            tmp_string.append(" se_tmp");
  1411.            i.append_in(tmp_string);
  1412.            tmp_string.append(fz_00);
  1413.         end;
  1414.         i := i - 1;
  1415.      end;
  1416.      if Result then
  1417.         se_tmp_level := se_tmp_level + 1;
  1418.         out_c.put_string(tmp_string);
  1419.      end;
  1420.       end;
  1421.  
  1422.    se_tmp_close_declaration is
  1423.       do
  1424.      check
  1425.         se_tmp_level > 0
  1426.      end;
  1427.      se_tmp_level := se_tmp_level - 1;
  1428.      out_c.put_string(fz_12);
  1429.      if se_tmp_level = 0 then
  1430.         se_tmp_list.clear;
  1431.      end;
  1432.       end;
  1433.  
  1434. feature {RUN_FEATURE}
  1435.  
  1436.    se_tmp_add(rf: RUN_FEATURE) is
  1437.       do
  1438.      se_tmp_list.add_last(rf);
  1439.       end;
  1440.  
  1441.    se_tmp_open(rf: RUN_FEATURE): INTEGER is
  1442.      -- Result >= 0 implies a temporary variable is used and thus
  1443.      -- `se_tmp_close' must be called.
  1444.      -- Result < 0 indicate that no temporary variable is mandatory.
  1445.       require
  1446.      rf.result_type /= Void
  1447.       local
  1448.      rt: TYPE;
  1449.       do
  1450.      rt := rf.result_type;
  1451.      Result := se_tmp_list.fast_index_of(rf);
  1452.      if se_tmp_list.valid_index(Result) then 
  1453.         check
  1454.            rt.is_user_expanded and then not rt.is_dummy_expanded
  1455.         end;
  1456.         se_tmp_list.put(Void,Result);
  1457.         out_c.put_string("(*(se_tmp");
  1458.         out_c.put_integer(Result);
  1459.         out_c.put_character('=');
  1460.      else
  1461.         Result := -1
  1462.      end;
  1463.       end;
  1464.  
  1465.    se_tmp_close(i: INTEGER) is
  1466.       do
  1467.      check
  1468.         se_tmp_list.item(i) = Void
  1469.      end;
  1470.      out_c.put_string(",&se_tmp");
  1471.      out_c.put_integer(i);
  1472.      out_c.put_string(fz_13);
  1473.       end;
  1474.  
  1475. feature {BIT_CONSTANT}
  1476.  
  1477.    register_bit_constant(bc: BIT_CONSTANT) is
  1478.       require
  1479.      bc.result_type.is_c_unsigned_ptr
  1480.       do
  1481.      if bit_constant_pool = void then
  1482.         !!bit_constant_pool.with_capacity(4);
  1483.      end;
  1484.      bit_constant_pool.add_last(bc);
  1485.      out_c.put_string(fz_se_bit_constant);
  1486.      out_c.put_integer(bit_constant_pool.upper);
  1487.       end;
  1488.  
  1489.    bit_constant_definition is
  1490.       local
  1491.      i: INTEGER;
  1492.      bc: BIT_CONSTANT;
  1493.      type_bit: TYPE_BIT;
  1494.       do
  1495.      if bit_constant_pool /= Void then
  1496.         from
  1497.            i := bit_constant_pool.upper;
  1498.         until
  1499.            i < 0
  1500.         loop
  1501.            tmp_string.clear;
  1502.            bc := bit_constant_pool.item(i)
  1503.            type_bit := bc.result_type;
  1504.            tmp_string.clear;
  1505.            type_bit.c_type_for_argument_in(tmp_string);
  1506.            tmp_string.extend(' ');
  1507.            tmp_string.append(fz_se_bit_constant);
  1508.            i.append_in(tmp_string);
  1509.            put_extern7(tmp_string);
  1510.            out_c.put_character('{');
  1511.            bc.c_define;
  1512.            out_c.put_character('}');
  1513.            out_c.put_character(';');
  1514.            out_c.put_character('%N');
  1515.            i := i - 1;
  1516.         end;
  1517.      end;
  1518.       end;
  1519.  
  1520. feature {RUN_CLASS,SWITCH_COLLECTION,MANIFEST_STRING_POOL}
  1521.  
  1522.    padding_here is
  1523.      -- Add some padding space ate the end of some RUN_CLASS or 
  1524.      -- at the end of a family of switch functions.
  1525.       local
  1526.      tabbing: INTEGER;
  1527.       do
  1528.      tabbing := elt_c_count_max // 30;
  1529.      if elt_c_count \\ tabbing > 0 then
  1530.         elt_c_count := elt_c_count // tabbing;
  1531.         elt_c_count := (elt_c_count + 1) * tabbing;
  1532.      end;
  1533.       end;
  1534.  
  1535. feature {SWITCH}
  1536.  
  1537.    finished_switch(running_count: INTEGER) is
  1538.      -- Add some padding space.
  1539.       do
  1540.      elt_c_count := elt_c_count + 4 * running_count;
  1541.       end;
  1542.  
  1543. feature {NATIVE_C_PLUS_PLUS}
  1544.  
  1545.    c_plus_plus_register(native: NATIVE_C_PLUS_PLUS) is
  1546.       do
  1547.      if c_plus_plus = Void then
  1548.         !!c_plus_plus.with_capacity(64);
  1549.      end;
  1550.      c_plus_plus.add_last(native);
  1551.       end;
  1552.  
  1553.    add_include(include: STRING) is
  1554.       do
  1555.      add_include_on(out_h,include);
  1556.       end;
  1557.  
  1558.    add_include_on(output: STD_FILE_WRITE; include: STRING) is
  1559.       do
  1560.      output.put_string("#include ");
  1561.      inspect
  1562.         include.first
  1563.      when '%"', '<' then
  1564.      else
  1565.         output.put_character('%"');
  1566.      end;
  1567.      output.put_string(include);
  1568.      inspect
  1569.         include.last
  1570.      when '%"', '>' then
  1571.      else
  1572.         output.put_character('%"');
  1573.      end;
  1574.      output.put_character('%N');
  1575.       end;
  1576.  
  1577. feature {RUN_FEATURE_2}
  1578.  
  1579.    attribute_read_removal(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS]): BOOLEAN is
  1580.       require
  1581.      small_eiffel.is_ready;
  1582.      r.count > 1
  1583.       local
  1584.      rf2a, rf2b: RUN_FEATURE_2;
  1585.      offseta, offsetb: INTEGER;
  1586.      rta, rtb: TYPE;
  1587.      i: INTEGER;
  1588.      rc: RUN_CLASS;
  1589.       do
  1590.      from
  1591.         Result := true;
  1592.         i := r.upper;
  1593.      until
  1594.         not Result or else i = 0
  1595.      loop
  1596.         rc := r.item(i);
  1597.         rf2b ?= rc.dynamic(up_rf);
  1598.         if rf2b /= Void then
  1599.            offsetb := rc.offset_of(rf2b);
  1600.         end;
  1601.         if rf2a = Void then
  1602.            rf2a := rf2b;
  1603.            offseta := offsetb;
  1604.         end;
  1605.         if rf2b = Void then
  1606.            Result := false;
  1607.         else
  1608.            Result := offseta = offsetb;
  1609.            if Result then
  1610.           rta := rf2a.result_type;
  1611.           rtb := rf2b.result_type;
  1612.           if rta.is_reference then
  1613.              Result := rtb.is_reference;
  1614.           elseif rta.run_time_mark = rtb.run_time_mark then
  1615.           elseif rta.is_native_array then
  1616.              if rta.generic_list.first.is_reference then
  1617.             Result := rtb.generic_list.first.is_reference;
  1618.              end;
  1619.           else
  1620.              Result := false;
  1621.           end;
  1622.            end
  1623.         end;
  1624.         i := i - 1;
  1625.      end;
  1626.       end;
  1627.  
  1628. feature {NONE}
  1629.  
  1630.    stupid_switch(up_rf: RUN_FEATURE): BOOLEAN is
  1631.       require
  1632.      small_eiffel.is_ready;
  1633.      up_rf.run_class.running /= Void
  1634.       local
  1635.      r: ARRAY[RUN_CLASS];
  1636.       do
  1637.      r := up_rf.run_class.running;
  1638.      if r.count > 1 then
  1639.         Result := stupid_switch_n(up_rf,r);
  1640.      else
  1641.         Result := true;
  1642.      end;
  1643.       end;
  1644.  
  1645.    stupid_switch_n(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS]): BOOLEAN is
  1646.       require
  1647.      small_eiffel.is_ready;
  1648.      r.count > 1
  1649.       local
  1650.      stupid: STRING;
  1651.       do
  1652.      if small_eiffel.same_base_feature(up_rf,r) then
  1653.         stupid := up_rf.stupid_switch(r);
  1654.         if stupid /= Void then
  1655.            put_comment(stupid);
  1656.            Result := true;
  1657.         end;
  1658.      else 
  1659.         Result := attribute_read_removal(up_rf,r);
  1660.         if Result then
  1661.            put_comment("SSWA2");
  1662.         end;
  1663.      end;
  1664.       end;
  1665.  
  1666.    c_plus_plus: FIXED_ARRAY[NATIVE_C_PLUS_PLUS];
  1667.  
  1668.    c_plus_plus_definitions is
  1669.       local
  1670.      cpp_path_h, cpp_path_c: STRING;
  1671.      i: INTEGER;
  1672.      no_split_save: BOOLEAN;
  1673.       do
  1674.      if c_plus_plus /= Void then
  1675.         no_split_save := no_split;
  1676.         no_split := true;
  1677.         echo.put_string("C++ external definitions.%N");
  1678.         cpp_path_h := system_tools.path_h.twin;
  1679.         cpp_path_h.remove_last(2);
  1680.         cpp_path_h.append("_external_cpp");
  1681.         cpp_path_c := cpp_path_h.twin;
  1682.         cpp_path_h.append(h_suffix);
  1683.         cpp_path_c.append(c_plus_plus_suffix);
  1684.         echo.sfw_connect(out_h,cpp_path_h);
  1685.         echo.sfw_connect(out_c,cpp_path_c);
  1686.         add_first_include(cpp_path_h);
  1687.         system_tools.add_c_plus_plus_file(cpp_path_c);
  1688.         sys_runtime_h("c_plus_plus");
  1689.         if c_plus_plus /= Void then
  1690.            from
  1691.           i := c_plus_plus.upper;
  1692.            until
  1693.           i < 0
  1694.            loop
  1695.           c_plus_plus.item(i).c_plus_plus_definition;
  1696.           i := i - 1;
  1697.            end;
  1698.         end;
  1699.         out_h.disconnect;
  1700.         out_c.disconnect;
  1701.         no_split := no_split_save;
  1702.      end;
  1703.       end;
  1704.  
  1705.    echo_make is
  1706.       do
  1707.      out_make.put_string(tmp_string);
  1708.      out_make.put_character('%N');
  1709.       end;
  1710.  
  1711.    out_c: STD_FILE_WRITE is
  1712.      -- The current *.c output file.
  1713.       once
  1714.      !!Result.make;
  1715.       end;
  1716.  
  1717.    out_h: STD_FILE_WRITE;
  1718.      -- The *.h output file.
  1719.  
  1720.    current_out: STD_FILE_WRITE;
  1721.      -- Is `out_c' or `out_h'.
  1722.  
  1723.    out_make: STD_FILE_WRITE is
  1724.      -- The *.make output file.
  1725.       once
  1726.      !!Result.make;
  1727.       end;
  1728.  
  1729.    incr_elt_c_count(i: INTEGER) is
  1730.      -- May break the C file here.
  1731.       do
  1732.      check
  1733.         out_c.is_connected;
  1734.      end;
  1735.      if no_split then
  1736.      else
  1737.         elt_c_count := elt_c_count + i;
  1738.         if elt_c_count >= elt_c_count_max then
  1739.            elt_c_count := 0;
  1740.            out_c.put_character('%N');
  1741.            out_c.disconnect;
  1742.            split_count := split_count + 1;
  1743.            path_c_in(path_c,split_count);
  1744.            backup_sfw_connect(out_c,path_c);
  1745.            add_first_include(path_h);
  1746.            if current_out /= out_h then
  1747.           current_out := out_c;
  1748.            end;
  1749.         end;
  1750.      end;
  1751.       end;
  1752.  
  1753.    no_args_to_eval: BOOLEAN is
  1754.      -- True if there is no C code to produce to eval arguments.
  1755.      -- For example because there are  no arguments or because
  1756.      -- we are inside a switching function for example.
  1757.       require
  1758.      small_eiffel.is_ready
  1759.       local
  1760.      code: INTEGER;
  1761.      args: EFFECTIVE_ARG_LIST;
  1762.       do
  1763.      code := stack_code.item(top);
  1764.      inspect
  1765.         code
  1766.      when C_direct_call,
  1767.         C_check_id,
  1768.         C_inside_new,
  1769.         C_same_target
  1770.       then
  1771.         args := stack_args.item(top);
  1772.         if args = Void then
  1773.            Result := true;
  1774.         else
  1775.            Result := args.can_be_dropped;
  1776.         end;
  1777.      when C_inline_dca then
  1778.         top := top - 1;
  1779.         Result := no_args_to_eval;
  1780.         top := top + 1;
  1781.      else
  1782.         Result := true;
  1783.      end;
  1784.       end;
  1785.  
  1786.    c_inline_h_mem: FIXED_ARRAY[STRING] is
  1787.       once
  1788.      !!Result.with_capacity(4);
  1789.       end;
  1790.  
  1791.    se_evobt(rf: RUN_FEATURE; target: EXPRESSION) is
  1792.       require
  1793.      rf /= Void;
  1794.      target /= Void
  1795.       do
  1796.      sure_void_count := sure_void_count + 1;
  1797.      put_character('(');
  1798.      if run_control.no_check then
  1799.         put_string("se_evobt");
  1800.         put_character('(');
  1801.         target.compile_to_c;
  1802.         put_character(',');
  1803.         put_position(target.start_position);
  1804.         put_character(')');
  1805.      else
  1806.         put_string("/*se_evobt*/");
  1807.         target.compile_to_c;
  1808.         put_character(',');
  1809.         exceptions_handler.se_evobt;
  1810.      end;
  1811.      if rf.result_type /= Void then
  1812.         put_character(',');
  1813.         rf.result_type.c_initialize;
  1814.      end;
  1815.      put_character(')');
  1816.      if rf.result_type = Void then
  1817.         put_string(fz_00);
  1818.      end;
  1819.       end;
  1820.  
  1821.    push_check(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1822.       require
  1823.      rf /= Void;
  1824.      t /= Void;
  1825.       do
  1826.      stack_push(C_check_id);
  1827.      stack_rf.put(rf,top);
  1828.      stack_target.put(t,top);
  1829.      stack_args.put(args,top);
  1830.       end;
  1831.  
  1832.    expanded_initializer(t: TYPE; a: RUN_FEATURE) is
  1833.      -- ***** CHANGE THIS ******
  1834.      -- Call the expanded initializer for type `t' if any.
  1835.      -- The result is assigned in writable `w' or to attribute
  1836.      -- `a' of the brand new created object in "n".
  1837.       require
  1838.      t.is_expanded;
  1839.      a /= Void
  1840.       local
  1841.      rf: RUN_FEATURE;
  1842.       do
  1843.      rf := t.expanded_initializer;
  1844.      if rf /= Void then
  1845.         stack_push(C_expanded_initialize);
  1846.         stack_target.put(Void,top);
  1847.         stack_rf.put(a,top);
  1848.         direct_call_count := direct_call_count + 1;
  1849.         rf.mapping_c;
  1850.         pop;
  1851.      end;
  1852.       end;
  1853.  
  1854.    use_switch(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS];
  1855.           t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1856.       require
  1857.      up_rf /= Void;
  1858.      r.count > 1
  1859.      t /= Void;
  1860.      on_c;
  1861.       local
  1862.      rt: TYPE;
  1863.      rc: RUN_CLASS;
  1864.      rf: RUN_FEATURE;
  1865.      switch: SWITCH;
  1866.      tmp_expanded_idx: INTEGER;
  1867.      cast: BOOLEAN;
  1868.       do
  1869.      rt := up_rf.result_type;
  1870.      if run_control.boost and then stupid_switch(up_rf) then
  1871.         switch_collection.remove(up_rf);
  1872.         out_c.put_string(fz_open_c_comment);
  1873.         out_c.put_character('X');
  1874.         out_c.put_integer(up_rf.current_type.id);
  1875.         out_c.put_string(up_rf.name.to_string);
  1876.         out_c.put_string(fz_close_c_comment);
  1877.         if rt /= Void and then rt.is_native_array then
  1878.            cast := true;
  1879.            out_c.put_string(fz_b7);
  1880.            out_c.put_integer(rt.id);
  1881.            out_c.put_character(')');
  1882.            out_c.put_character('(');
  1883.         end;
  1884.         rc := r.item(1);
  1885.         rf := rc.dynamic(up_rf);
  1886.         push_direct(rf,t,args);
  1887.         rf.mapping_c;
  1888.         pop;
  1889.         if cast then
  1890.            out_c.put_character(')');
  1891.            out_c.put_character(')');
  1892.         end;
  1893.      else
  1894.         switch_count := switch_count + 1;
  1895.         if rt /= Void then
  1896.            tmp_expanded_idx := se_tmp_open(up_rf);
  1897.         end;
  1898.         out_c.put_string(switch.name(up_rf));
  1899.         out_c.put_character('(');
  1900.         if run_control.no_check then
  1901.            out_c.put_string("&ds,");
  1902.            put_position(t.start_position)
  1903.            out_c.put_character(',');
  1904.         end;
  1905.         t.compile_to_c;
  1906.         if args /= Void then
  1907.            out_c.put_character(',');
  1908.            args.compile_to_c(up_rf.arguments);
  1909.         end;
  1910.         put_character(')');
  1911.         if rt = Void then
  1912.            out_c.put_string(fz_00);
  1913.         elseif tmp_expanded_idx >= 0 then
  1914.            se_tmp_close(tmp_expanded_idx);
  1915.         end;
  1916.      end;
  1917.       end;
  1918.  
  1919.    define_initialize_eiffel_runtime(rf3: RUN_FEATURE_3) is
  1920.       require
  1921.      on_c
  1922.       local
  1923.      no_check: BOOLEAN;
  1924.      rc: RUN_CLASS;
  1925.      ct: TYPE;
  1926.       do
  1927.      no_check := run_control.no_check;
  1928.      ct := rf3.current_type;
  1929.      rc := rf3.run_class;
  1930.      echo.put_string("Define initialize stuff.%N");
  1931.      small_eiffel.define_extern_tables;
  1932.      put_c_heading("void initialize_eiffel_runtime(int argc,char*argv[])");
  1933.      if no_check then
  1934.         out_c.put_string(
  1935.                  "se_frame_descriptor irfd={%"Initialysing runtime.%",0,0,%"%",1};%N%
  1936.                                              %se_dump_stack ds = {NULL,NULL,0,NULL,NULL};%N%
  1937.                                              %ds.fd=&irfd;%N%
  1938.                                              %ds.caller=se_dst;%N");
  1939.      end;
  1940.      out_c.put_string("se_argc=argc;%Nse_argv=argv;%N");
  1941.      gc_handler.initialize_runtime;
  1942.      exceptions_handler.initialize_runtime;
  1943.      if no_check then
  1944.         small_eiffel.initialize_path_table;
  1945.      end;
  1946.      if run_control.generator_used then
  1947.         small_eiffel.initialize_generator;
  1948.      end;
  1949.      if run_control.generating_type_used then
  1950.         small_eiffel.initialize_generating_type;
  1951.      end;
  1952.      if not exceptions_handler.used then
  1953.         out_c.put_string(
  1954.                  "#ifdef SIGINT%Nsignal(SIGINT,sigrsp);%N#endif%N%
  1955.                  %#ifdef SIGQUIT%Nsignal(SIGQUIT,sigrsp);%N#endif%N%
  1956.                  %#ifdef SIGTERM%Nsignal(SIGTERM,sigrsp);%N#endif%N%
  1957.                  %#ifdef SIGBREAK%Nsignal(SIGBREAK,sigrsp);%N#endif%N%
  1958.                  %#ifdef SIGKILL%Nsignal(SIGKILL,sigrsp);%N#endif%N");
  1959.      end;
  1960.      manifest_string_pool.c_call_initialize;
  1961.      once_routine_pool.c_pre_compute;
  1962.      if run_control.trace then
  1963.         out_c.put_string("se_trace_flag=1;%N");
  1964.      end;
  1965.      if not gc_handler.is_off then
  1966.         out_c.put_string("gc_is_off=0;%N");
  1967.      end;
  1968.      gc_handler.allocation_of(fz_eiffel_root_object,rc);
  1969.      if run_control.no_check then
  1970.         out_c.put_string("se_dst=NULL;%N");
  1971.      end;
  1972.      out_c.put_string(fz_12);
  1973.       ensure
  1974.      on_c
  1975.       end;
  1976.  
  1977.    define_is_equal_prototype(id: INTEGER) is
  1978.       do
  1979.      tmp_string.copy("T6 r");
  1980.      (id).append_in(tmp_string);
  1981.      tmp_string.append(as_is_equal);
  1982.      tmp_string.append("(T");
  1983.      (id).append_in(tmp_string);
  1984.      tmp_string.append("*C, T0*a1)");
  1985.      out_h.put_string(tmp_string);
  1986.      out_c.put_string(tmp_string);
  1987.       end;
  1988.  
  1989.    check_assertion_mode: STRING;
  1990.  
  1991.    inspect_level: INTEGER;
  1992.  
  1993.    inline_level: INTEGER;
  1994.  
  1995.    check_id(e: EXPRESSION; id: INTEGER) is
  1996.      -- Produce a C expression checking that `e' is not void and
  1997.      -- that `e' is really of type `id'.
  1998.      -- The result of the C expression is the pointer to the
  1999.      -- corresponding Object.
  2000.       require
  2001.      e.result_type.run_type.is_reference;
  2002.      id > 0;
  2003.       do
  2004.      if run_control.no_check then
  2005.         put_string("((T");
  2006.         put_integer(id);
  2007.         put_string("*)ci(");
  2008.         put_integer(id);
  2009.         put_character(',');
  2010.         e.compile_to_c;
  2011.         put_character(',');
  2012.         put_position(e.start_position);
  2013.         put_string(fz_13);
  2014.         check_id_count := check_id_count + 1;
  2015.      else
  2016.         e.compile_to_c;
  2017.         direct_call_count := direct_call_count + 1;
  2018.      end;
  2019.       end;
  2020.  
  2021.    same_base_feature(r: ARRAY[RUN_CLASS]; up_rf: RUN_FEATURE): BOOLEAN is
  2022.      -- True if all have the same final name and the same base_feature.
  2023.       require
  2024.      not r.empty;
  2025.      up_rf /= Void
  2026.       local
  2027.      i: INTEGER;
  2028.      up_bf, bf: E_FEATURE;
  2029.      up_name, name: FEATURE_NAME;
  2030.      rf: RUN_FEATURE;
  2031.       do
  2032.      from
  2033.         up_bf := up_rf.base_feature;
  2034.         up_name := up_rf.name;
  2035.         i := r.lower;
  2036.         Result := true;
  2037.      until
  2038.         not Result or else i > r.upper
  2039.      loop
  2040.         rf := r.item(i).dynamic(up_rf);
  2041.         bf := rf.base_feature;
  2042.         name := rf.name;
  2043.         Result := name.is_equal(up_name) and then bf = up_bf;
  2044.         i := i + 1;
  2045.      end;
  2046.       end;
  2047.  
  2048.    tmp_string: STRING is
  2049.       once
  2050.      !!Result.make(256);
  2051.       end;
  2052.  
  2053.    tmp_string2: STRING is
  2054.       once
  2055.      !!Result.make(128);
  2056.       end;
  2057.  
  2058.    tmp_string3: STRING is
  2059.       once
  2060.      !!Result.make(128);
  2061.       end;
  2062.  
  2063.    need_invariant(target_type: TYPE): RUN_CLASS is
  2064.      -- Give the good RUN_CLASS when `target_type' need some
  2065.      -- class invariant checking.
  2066.       require
  2067.      target_type.is_run_type
  2068.       do
  2069.      if run_control.invariant_check then
  2070.         Result := target_type.run_type.run_class;
  2071.         if Result.at_run_time and then
  2072.            Result.class_invariant /= Void then
  2073.         else
  2074.            Result := Void;
  2075.         end;
  2076.      end;
  2077.       end;
  2078.    
  2079.    split_count: INTEGER;
  2080.      -- Number of *.c files.
  2081.  
  2082.    elt_c_count: INTEGER;
  2083.      -- Number of elements already in current *.c file.
  2084.  
  2085.    elt_c_count_max: INTEGER is 5000; 
  2086.      -- Approximate number of elements/lines in each generated C file.
  2087.      -- Modification of this constant allow you to change the size of 
  2088.      -- generated C files. To have less C files, just increase this 
  2089.      -- value.
  2090.      -- Finally, because Windows 98 has a limited command line 
  2091.      -- buffer, the value is set in order to have no more than 30 
  2092.      -- slices for the `compile_to_c' command.
  2093.  
  2094.    path_h: STRING is
  2095.       once
  2096.      Result := system_tools.path_h;
  2097.       ensure
  2098.      Result.has_suffix(h_suffix)
  2099.       end;
  2100.  
  2101.    path_c: STRING is
  2102.       once
  2103.      if no_split then
  2104.         Result := path_h.twin;
  2105.         Result.remove_last(1);
  2106.         Result.extend('c');
  2107.      else
  2108.         split_count := 1;
  2109.         !!Result.make(path_h.count + 4);
  2110.         path_c_in(Result,split_count);
  2111.      end;
  2112.       ensure
  2113.      Result.has_suffix(c_suffix);
  2114.       end;
  2115.  
  2116.    path_make: STRING is
  2117.       once
  2118.      Result := path_h.twin;
  2119.      Result.remove_last(2);
  2120.      Result.append(system_tools.make_suffix);
  2121.       ensure
  2122.      Result.has_suffix(system_tools.make_suffix);
  2123.       end;
  2124.  
  2125.    add_first_include(the_first_include: STRING) is
  2126.       do
  2127.      put_banner(out_c);
  2128.      add_include_on(out_c,the_first_include);
  2129.       end;
  2130.  
  2131.    put_banner(output: STD_FILE_WRITE) is
  2132.       require
  2133.      output /= Void;
  2134.      output.is_connected;
  2135.       do
  2136.      output.put_string(fz_open_c_comment);
  2137.      output.put_string(
  2138.                "%N-- ANSI C code generated by :%N");
  2139.      output.put_string(small_eiffel.copyright);
  2140.      output.put_string(fz_close_c_comment);
  2141.      output.put_character('%N');
  2142.       end;
  2143.  
  2144.    c_code_saved: BOOLEAN;
  2145.  
  2146.    get_inline_ms: MANIFEST_STRING is
  2147.       local
  2148.      e: EXPRESSION;
  2149.       do
  2150.      e := stack_args.item(top).expression(1);
  2151.      Result ?= e;
  2152.      if Result = Void then
  2153.         eh.add_position(e.start_position);
  2154.         fatal_error("Bad usage of C inlining (argument%
  2155.             % is not a manifest string).");
  2156.      end;
  2157.       end;
  2158.  
  2159.    backup_sfw_connect(sfw: STD_FILE_WRITE; c_path: STRING) is
  2160.       require
  2161.      not no_split
  2162.       local
  2163.      object_suffix: STRING;
  2164.       do
  2165.      object_suffix := system_tools.object_suffix;
  2166.      tmp_path.copy(c_path);
  2167.      tmp_path.remove_last(2);
  2168.      tmp_path.append(object_suffix);
  2169.      if file_exists(tmp_path) then
  2170.         if file_exists(c_path) then
  2171.            c_path.put('d',c_path.count);
  2172.         end;
  2173.      end;
  2174.      echo.sfw_connect(sfw,c_path);
  2175.       end;
  2176.  
  2177.    path_c_in(str: STRING; number: INTEGER) is
  2178.       do
  2179.      str.clear;
  2180.      str.append(path_h);
  2181.      str.remove_last(2);
  2182.      number.append_in(str);
  2183.      str.extend('.');
  2184.      str.extend('c');
  2185.       end;
  2186.  
  2187.    write_make_file_split is
  2188.       require
  2189.      not no_split
  2190.       local
  2191.      i: INTEGER;
  2192.      no_change, recompile: BOOLEAN;
  2193.      output_name: STRING;
  2194.       do
  2195.      no_change := true;
  2196.      from
  2197.         i := split_count;
  2198.      until
  2199.         i = 0
  2200.      loop
  2201.         recompile := true;
  2202.         path_c_in(tmp_path,i);
  2203.         tmp_string.copy(tmp_path);
  2204.         tmp_string.put('d',tmp_string.count);
  2205.         if file_exists(tmp_string) then
  2206.            if file_tools.same_files(tmp_path,tmp_string) then
  2207.           echo.put_string(fz_01);
  2208.           echo.put_string(tmp_path);
  2209.           echo.put_string("%" not changed.%N");
  2210.           echo.file_removing(tmp_string);
  2211.           recompile := false;
  2212.            else
  2213.           echo.file_renaming(tmp_string,tmp_path);
  2214.            end;
  2215.         end;
  2216.         if recompile then
  2217.            tmp_string2.copy(path_h);
  2218.            tmp_string2.remove_last(2);
  2219.            i.append_in(tmp_string2);
  2220.            tmp_string2.extend('.');
  2221.            tmp_string2.extend('c');
  2222.            system_tools.split_mode_c_compiler_command(tmp_string,
  2223.                               tmp_string2);
  2224.            echo_make;
  2225.            no_change := false;
  2226.         end;
  2227.         i := i - 1;
  2228.      end;
  2229.      output_name := run_control.output_name;
  2230.      if no_change and then output_name /= Void then
  2231.         no_change := file_exists(output_name)
  2232.      else
  2233.         no_change := false;
  2234.      end;
  2235.      if no_change then
  2236.         echo.put_string("Executable is up-to-date %
  2237.                 %(no C compilation, no linking done).%N");
  2238.      else
  2239.         tmp_string2.copy(path_h);
  2240.         tmp_string2.remove_last(2);
  2241.         system_tools.split_mode_linker_command(tmp_string,
  2242.                            tmp_string2,split_count);
  2243.         echo_make;
  2244.      end;
  2245.       end;
  2246.  
  2247.    write_make_file_no_split is
  2248.       require
  2249.      no_split
  2250.       do
  2251.      system_tools.no_split_mode_command(tmp_string,path_c);
  2252.      echo_make;
  2253.       end;
  2254.  
  2255.    common_put_target is
  2256.       local
  2257.      rf: RUN_FEATURE;
  2258.      flag: BOOLEAN;
  2259.      e: EXPRESSION;
  2260.      ct: TYPE;
  2261.       do
  2262.      inspect
  2263.         stack_code.item(top)
  2264.      when C_inside_twin then
  2265.         rf := stack_rf.item(top);
  2266.         ct := rf.current_type;
  2267.         if ct.is_reference then
  2268.            out_c.put_character('(');
  2269.            ct.mapping_cast;
  2270.            out_c.put_character('R');
  2271.            out_c.put_character(')');
  2272.         else
  2273.            out_c.put_character('&');
  2274.            out_c.put_character('R');
  2275.         end;
  2276.      when C_inside_new then
  2277.         out_c.put_character('n');
  2278.      when C_switch then
  2279.         rf := stack_rf.item(top);
  2280.         flag := call_invariant_start(rf.current_type);
  2281.         out_c.put_string("((T");
  2282.         out_c.put_integer(rf.id);
  2283.         out_c.put_string("*)C)");
  2284.         if flag then
  2285.            call_invariant_end;
  2286.         end;
  2287.      when C_expanded_initialize then
  2288.         e := stack_target.item(top);
  2289.         if e /= Void then
  2290.            out_c.put_character('&');
  2291.            e.compile_to_c;
  2292.         else
  2293.            out_c.put_string("&n->_");
  2294.            out_c.put_string(stack_rf.item(top).name.to_string);
  2295.         end;
  2296.      when C_inline_one_pc then
  2297.         print_current;
  2298.      when C_precursor then
  2299.         out_c.put_character('C');
  2300.      end;
  2301.       end;
  2302.  
  2303.    put_file(sfr: STD_FILE_READ; output: STD_FILE_WRITE) is
  2304.       require
  2305.      not sfr.end_of_input
  2306.       do
  2307.      from
  2308.         sfr.read_character;
  2309.      until
  2310.         sfr.end_of_input
  2311.      loop
  2312.         output.put_character(sfr.last_character);
  2313.         sfr.read_character;
  2314.      end;
  2315.      sfr.disconnect;
  2316.       ensure
  2317.      not sfr.is_connected
  2318.       end;
  2319.  
  2320.    really_define_c_main(rf3: RUN_FEATURE_3) is
  2321.       require
  2322.      not no_main
  2323.       local
  2324.      id: INTEGER;
  2325.      rc: RUN_CLASS;
  2326.      ct: TYPE;
  2327.       do
  2328.      echo.put_string("Define C main function.%N");
  2329.      ct := rf3.current_type;
  2330.      rc := rf3.run_class;
  2331.      id := rc.id;
  2332.      system_tools.put_c_main_function_type(out_c);
  2333.      out_c.put_string(" main(int argc,char*argv[]){%N%
  2334.               %initialize_eiffel_runtime(argc,argv);%N");
  2335.      out_c.put_string("{T");
  2336.      out_c.put_integer(id);
  2337.      out_c.put_string("*n=eiffel_root_object;%N");
  2338.      if run_control.no_check then
  2339.         out_c.put_string("se_frame_descriptor root={%"System root.%",1,0,%"");
  2340.         c_frame_descriptor_format.clear;
  2341.         ct.c_frame_descriptor;
  2342.         out_c.put_string(c_frame_descriptor_format);
  2343.         out_c.put_string("%",1};%N%
  2344.                    %se_dump_stack ds;%N%
  2345.                    %ds.fd=&root;%N%
  2346.                    %ds.current=((void**)(&n));%N");
  2347.         put_position_in_ds(rf3.start_position);
  2348.         out_c.put_string("ds.caller=NULL;%Nse_dst=&ds;/*link*/%N");
  2349.      end;
  2350.      expanded_attributes(ct);
  2351.      push_new(rf3,Void);
  2352.      rf3.mapping_c;
  2353.      pop;
  2354.      if run_control.invariant_check then
  2355.         if rc.class_invariant /= Void then
  2356.            out_c.put_string(fz_se_i);
  2357.            out_c.put_integer(id);
  2358.            out_c.put_string("(&ds,n);%N");
  2359.         end;
  2360.      end;
  2361.      gc_handler.gc_info_before_exit;
  2362.      system_tools.put_c_main_function_exit(out_c);
  2363.       end;
  2364.  
  2365.    bit_constant_pool: FIXED_ARRAY[BIT_CONSTANT];
  2366.  
  2367.    fz_se_bit_constant: STRING is "se_bit_constant";
  2368.  
  2369.    se_tmp_level: INTEGER;
  2370.  
  2371.    se_tmp_list: FIXED_ARRAY[RUN_FEATURE] is
  2372.       once
  2373.      !!Result.with_capacity(4);
  2374.       end;
  2375.  
  2376.    fz_base: STRING is "base";
  2377.  
  2378.    fz_no_check: STRING is "no_check";
  2379.  
  2380. end -- C_PRETTY_PRINTER
  2381.  
  2382.